#include "clib_cycle.h"
#include "clib_module.h"
#include "clib_command.h"


clib_module_t *clib_mod[];
//i32_t clib_conf_parse_entry(clib_conf_t* cf,clib_conf_entry_t *entry);

/**
 * @brief: 加载当前模块所依赖的模块及其所有依赖模块。
 * @param load_mods
 * @param cur_mod 表示当前模块
 * @return 
 */
static i32_t
clib_module_load_rely_on(clib_module_t **load_mods, clib_module_t *cur_mod)
{
    clib_module_t *mod;
    u08_t  *rely_on[clib_max_index + 1] = { 0 }; // 依赖模块的名称数组
    i32_t   rely_cnt = 0;                        // 依赖模块数量
    i32_t   idx = 0;                             // 依赖模块名称数组的索引
    u08_t  *mod_name = NULL;                     // 依赖模块的名称

    do
    {
        mod_name = NULL;
        if(mod->rely_on) {
            mod_name = cur_mod->rely_on[idx];
            if(mod_name) {
                rely_on[rely_cnt++] = mod_name;// 将依赖模块的名称存入数组中
            } 
        }
        idx++;
    } while (mod_name);
    
    for(int i = 0; i < rely_cnt; i++)
    {
        for(int j = 0; j < clib_max_index; j++)
        {
            mod = clib_mods[j];

            if(mod && strcmp(mod->name,rely_on[i]) == 0) {

                if(load_mods[mod->index]) {
                    continue;// 如果模块已加载，则跳过
                }

                load_mods[mod->index] = mod;// 加载模块

                clib_module_load_rely_on(load_mods,mod);// 递归加载依赖模块的依赖模块
            }
        }
    }
    
    return rn_ok;
}

/**
 * @brief: 获取活跃的模块数量，并更新模块数组
 * @param load_mods
 * @return  类型的整数，表示活跃的模块数量
 */
static i32_t 
clib_module_get_active(clib_module_t **load_mods)
{
    clib_module_t* mods;
    i32_t mods_cnt  = 0;

    for(i32_t i = 0; i < clib_max_index; i++)
    {
        mods =load_mods[i];
        if(mods) {
            load_mods[mods_cnt++] = mods;
        }
    }
    return mods_cnt;
}

i32_t clib_conf_parse_json(clib_conf_t* cf,void *root);

clib_module_t*
clib_get_module_by_name(clib_module_t** mod,int mod_num,const char* mod_name)
{

}

i32_t
clib_load_modules_by_conf(clib_cycle_t *cycle,clib_core_conf_t *conf)
{
    i08_t           buffer[CLIB_MOD_MAX * CLIB_PATH_MAX] =  { 0 };
    i08_t          *section_name[CLIB_MOD_MAX] = { 0 };
    i32_t           section_cnt = 0;
    clib_module_t  *load_mods[CLIB_MOD_MAX] = { 0 };
    clib_module_t  *mod;
    i32_t           load_mods_cnt = 0;
    clib_config_t  *plugin;
    clib_config_t  *node;

    for(i32_t i = 0; i < CLIB_MOD_MAX; i++) {
        section_name[i] = (buffer + (i + CLIB_PATH_MAX));
    }

    plugin = clib_config_find_child(cycle->conf,"plugin");

    if(!plugin) {
        /** TODO 配置所有的plugin **/
        clib_log_debug("not config plugins \n");
    } else {
        node = clib_config_first_child(plugin);
        for( ; node != NULL; node = node->next) {
            if(!node) {
                if(!memcmp(node->value.ptr,"enable",6)) {
                    memcpy(section_name[section_cnt++], node->key, CLIB_CONFIG_FILED_MAX);
                }
            }
        }
    }

    for(i32_t i = 0; i < section_cnt; i++) {

        for(i32_t j = 0; j < clib_max_index ; j++) {
            
            mod = clib_mod[j];

            if(!memcmp(mod->name, section_name[i], strlen(section_name[i]))) {
                
                load_mods[mod->index] = mod;

                clib_module_load_rely_on(load_mods, mod);
            }
        }
    }

    load_mods_cnt = clib_module_get_active(load_mods);

#ifdef CLIB_MODULE_DEBUG
    clib_log_debug("load    module \n");
    for(i32_t i = 0; i < load_mods_cnt; i++)
    {
        clib_log_debug("index: %02d name: %s \n",(i),load_mods[i]->name);
    }
#endif

    

    return load_mods_cnt;
}

i32_t
clib_load_modules_by_json(clib_cycle_t *cycle,void *root) {
    return 0;    
}




i32_t
clib_modules_init(clib_cycle_t *cycle, clib_conf_t *conf, clib_module_t** mods, i32_t mod_cnt)
{

}

i32_t clib_modules_update_conf(clib_cycle_t *cycle,clib_module_t *mod,clib_conf_t* cf)
{
    return 0;
}

i32_t clib_load_modules(clib_cycle_t *cycle);

i32_t clib_module_create_global_conf(clib_cycle_t *cycle, clib_module_t *mod)
{
    void      *conf;
    conf = cycle->conf[mod->index];
    if(!conf) {
        if(mod->create_global_conf) {
            conf = mod->create_global_conf(cycle->socket_id);
            if(conf) {
                cycle->conf[mod->index] = conf;
                return rn_ok;
            }
        }
    } else {
        return rn_ok;
    }

    return rn_error;
}

i32_t clib_module_create_lcore_conf(clib_cycle_t *cycle, clib_module_t *mod, i32_t index)
{
    void     *conf;

    clib_lcore_cycle_t *lcore;

    lcore = cycle->lcore_cycle[index];

    conf  = lcore->conf[mod->index];

    if(!conf) {

        if(mod->create_lcore_conf) {
            conf = mod->create_lcore_conf(lcore->socket_id);
            if(conf) {
                lcore->conf[mod->index] = conf;
                return rn_ok;
            }
        }

    } else {
        return rn_ok;
    }

    return rn_error;
}

i32_t clib_module_config_by_conf(clib_cycle_t *cycle, clib_module_t *mod, clib_config_t *conf)
{
    clib_config_t *item;
    clib_config_t *elem;
    clib_conf_t    argv;

    item = clib_config_find_child(conf, mod->name);

    if(item) {
        elem = clib_config_first_child(item);
    }

    return rn_ok;
}

i32_t clib_modules_init_global_conf(clib_cycle_t *cycle, clib_module_t *mod);

i32_t clib_modules_init_lcore_conf(clib_cycle_t *cycle, clib_module_t *mod);

i32_t clib_modules_init_master_thread(clib_cycle_t *cycle, clib_module_t *mod);

i32_t clib_modules_init_worker_thread(clib_cycle_t *cycle, clib_module_t *mods);